namespace Nice157Advices.Advices
{
    public static class _43
    {
        public static void Go ()
        {
            ISalary<Programmer> s = new BaseSalaryCounter<Programmer> ();
            ISalary<Manager> t = new BaseSalaryCounter<Manager> ();
            PrintSalary (s);
            PrintSalary (t);
        }

        private static void PrintSalary (ISalary<Employee> e) => e.Pay ();

        /**
         * out 关键字 可以在泛型接口和委托中使用，用来让类型参数支持协变性。
         * 通过协变，可以使用比声明的参数派生类型更大的参数。
         *
         * /* NOTE
         * 在我们自己的代码中，如果要编写泛型接口，除非确定该接口中的泛型参数不涉及变体，否则都建议加上out关键字。协变增大了接口的使用范围，而且几乎不会带来什么副作用。
         */

        private interface ISalary<out T>
        {
            void Pay ();
        }

        private class BaseSalaryCounter<T> : ISalary<T>
        {
            public void Pay () => System.Console.WriteLine ("Pay base salary");
        }

        private class Employee
        {
            public string Name { get; set; }
        }

        private class Programmer : Employee { }
        private class Manager : Employee { }
    }
}